home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / FINDREPL.SWG / 0016_TAGLINES.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  5KB  |  194 lines

  1. { BOB SWART
  2.  
  3. Here it is, all new and much faster. I used an internal binary tree to manage
  4. the taglines. You can store up to the available RAM in taglines:
  5. }
  6.  
  7. {$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S+,T-,V-,X-}
  8. {$M 16384,0,655360}
  9. Uses
  10.   Crt;
  11. Type
  12.   TBuffer  = Array[0..$4000] of Char;
  13.  
  14. Const
  15.   Title = 'TagLines 0.2 by Bob Swart For Travis Griggs'#13#10;
  16.   Usage = 'Usage: TagLines inFile outFile'#13#10#13#10+
  17.           '       Taglines will remove dupicate lines from inFile.'#13#10+
  18.           '       Resulting Text is placed in outFile.'#13#10;
  19.  
  20.   NumLines: LongInt = 0; { total number of lines in InFile }
  21.   NmLdiv80: LongInt = 0; { NumLines div 80, For 'progress' }
  22.   CurrentL: LongInt = 0; { current lineno read from InFile }
  23.  
  24. Type
  25.   String80 = String[80];
  26.  
  27.   PBinTree = ^TBinTree;
  28.   TBinTree = Record
  29.                Info: String80;
  30.                left,right: PBinTree
  31.              end;
  32.  
  33. Var
  34.   InBuf,
  35.   OutBuf   : TBuffer;
  36.   InFile,
  37.   OutFile  : Text;
  38.   TagLine  : String80;
  39.   Root,
  40.   Current,
  41.   Prev     : PBinTree;
  42.   i        : Integer;
  43.   SaveExit : Pointer;
  44.  
  45.  
  46. Function CompStr(Var Name1,Name2: String): Integer; Assembler;
  47. { Author: drs. Robert E. Swart
  48. }
  49. Asm
  50.   push  DS
  51.   lds   SI,Name1               { ds:si pts to Name1       }
  52.   les   DI,Name2               { es:di pts to Name2       }
  53.   cld
  54.   lodsb                        { get String1 length in AL }
  55.   mov   AH,ES:[DI]             { get String2 length in AH }
  56.   inc   DI
  57.   mov   BX,AX                  { save both lengths in BX  }
  58.   xor   CX,CX                  { clear cx                 }
  59.   mov   CL,AL                  { get String1 length in CX }
  60.   cmp   CL,AH                  { equal to String2 length? }
  61.   jb    @Len                   { CX stores minimum length }
  62.   mov   CL,AH                  { of String1 and String2   }
  63.  @Len: jcxz  @Exit                  { quit if null             }
  64.  
  65.  @Loop: lodsb                        { String1[i] in AL         }
  66.   mov   AH,ES:[DI]             { String2[i] in AH         }
  67.   cmp   AL,AH                  { compare Str1 to Str2     }
  68.   jne   @Not                   { loop if equal            }
  69.   inc   DI
  70.   loop  @Loop                  { go do next Char          }
  71.   jmp   @Exit                  { Strings OK, Length also? }
  72.  
  73.  @Not: mov   BX,AX                  { BL = AL = String1[i],
  74.                                  BH = AH = String2[i]     }
  75.  @Exit: xor   AX,AX
  76.   cmp   BL,BH                  { length or contents comp  }
  77.   je    @Equal                 { 1 = 2: return  0         }
  78.   jb    @Lower                 { 1 < 2: return -1         }
  79.   inc   AX                     { 1 > 2: return  1         }
  80.   inc   AX
  81.  @Lower: dec   AX
  82.  @Equal: pop   DS
  83. end {CompStr};
  84.  
  85. Procedure Stop; Far;
  86. begin
  87.   ExitProc := SaveExit;
  88.   Close(InFile);
  89.   Close(OutFile);
  90. end {Stop};
  91.  
  92.  
  93. begin
  94.   Writeln(Title);
  95.   if Paramcount <> 2 then
  96.   begin
  97.     Writeln(Usage);
  98.     Halt
  99.   end;
  100.  
  101.   Assign(InFile,ParamStr(1));
  102.   SetTextBuf(InFile,InBuf);
  103.   Reset(InFile);
  104.   if IOResult <> 0 then
  105.   begin
  106.     WriteLn('Error: could not open ', ParamStr(1));
  107.     Halt(1)
  108.   end;
  109.  
  110.   Assign(OutFile,ParamStr(2));
  111.   SetTextBuf(OutFile,OutBuf);
  112.   Reset(OutFile);
  113.   if IOResult = 0 then
  114.   begin
  115.     WriteLn('Error: File ', ParamStr(2),' already exists');
  116.     Halt(2)
  117.   end;
  118.  
  119.   ReWrite(OutFile);
  120.   if IOResult <> 0 then
  121.   begin
  122.     WriteLn('Error: could not create ', ParamStr(2));
  123.     Halt(3)
  124.   end;
  125.  
  126.   SaveExit := ExitProc;
  127.   ExitProc := @Stop;
  128.  
  129.   While not eof(InFile) do
  130.   begin
  131.     readln(InFile);
  132.     Inc(NumLines);
  133.   end;
  134.   Writeln('There are ',NumLines,' lines in this File.'#13#10);
  135.   Writeln('Press any key to stop the search For duplicate lines');
  136.   NmLdiv80 := NumLines div 80;
  137.  
  138.   Root := nil;
  139.   reset(InFile);
  140.   While CurrentL <> NumLines do
  141.   begin
  142.     if KeyPressed then
  143.       Halt { calls Stop };
  144.     Inc(CurrentL);
  145.     if (CurrentL and NmLdiv80) = 0 then
  146.       Write('#');
  147.     readln(InFile,TagLine);
  148.  
  149.     if root = nil then { first TagLine }
  150.     begin
  151.       New(Root);
  152.       Root^.left := nil;
  153.       Root^.right := nil;
  154.       Root^.Info := TagLine;
  155.       Writeln(OutFile,tagLine)
  156.     end
  157.     else { binary search For TagLine }
  158.     begin
  159.       Current := Root;
  160.       Repeat
  161.         Prev := Current;
  162.         i := CompStr(Current^.Info,TagLine);
  163.         if i > 0 then
  164.           Current := Current^.left
  165.         else
  166.         if i < 0 then
  167.           Current := Current^.right
  168.       Until (i = 0) or (Current = nil);
  169.  
  170.       if i <> 0 then { TagLine not found }
  171.       begin
  172.         New(Current);
  173.         Current^.left := nil;
  174.         Current^.right := nil;
  175.         Current^.Info := TagLine;
  176.  
  177.         if i > 0 then
  178.           Prev^.left := Current { Current before Prev }
  179.         else
  180.           Prev^.right := Current { Current after Prev };
  181.         Writeln(OutFile,TagLine)
  182.       end
  183.     end
  184.   end;
  185.   Writeln(#13#10'100% Completed, result is in File ',ParamStr(2))
  186.   { close is done by Stop }
  187. end.
  188.  
  189. {
  190. > I also tried DJ's idea of the buffer of 65535 but it said the structure
  191. > was too large. So I used 64512.
  192. Always try to use a multiple of 4K, because the hard disk 'eats' space in these
  193. chunks. Reading/Writing in these chunks goes a lot faster that way.
  194. }